using Bridge.Test.NUnit;
using System;
using System.Collections.Generic;
using System.Text;

#if false
namespace Bridge.ClientTest.Text
{
    [Category(Constants.MODULE_ENCODING)]
    [TestFixture(TestNameFormat = "UTF8Encoding - {0}")]
    public class UTF8EncodingEncodeTests
    {
        public static IEnumerable<object[]> Encode_TestData()
        {
            // All ASCII chars
            for (char c = char.MinValue; c <= 0x7F; c++)
            {
                yield return new object[] { c.ToString(), 0, 1, new byte[] { (byte)c } };
                yield return new object[] { "a" + c.ToString() + "b", 1, 1, new byte[] { (byte)c } };
                yield return new object[] { "a" + c.ToString() + "b", 2, 1, new byte[] { 98 } };
                yield return new object[] { "a" + c.ToString() + "b", 0, 3, new byte[] { 97, (byte)c, 98 } };
            }

            // Misc ASCII and Unicode strings
            yield return new object[] { "FooBA" + EncodingHelpers.ToString(new int[] { 0x0400 }) + "R", 0, 7, new byte[] { 70, 111, 111, 66, 65, 208, 128, 82 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00C0 }) + "nima" + EncodingHelpers.ToString(new int[] { 0x0300 }) + "l", 0, 7, new byte[] { 195, 128, 110, 105, 109, 97, 204, 128, 108 } };
            yield return new object[] { "Test" + EncodingHelpers.ToString(new int[] { 0xD803, 0xDD75 }) + "Test", 0, 10, new byte[] { 84, 101, 115, 116, 240, 144, 181, 181, 84, 101, 115, 116 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0130 }), 0, 1, new byte[] { 196, 176 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD803, 0xDD75, 0xD803, 0xDD75, 0xD803, 0xDD75 }), 0, 6, new byte[] { 240, 144, 181, 181, 240, 144, 181, 181, 240, 144, 181, 181 } };
            yield return new object[] { "za" + EncodingHelpers.ToString(new int[] { 0x0306, 0x01FD, 0x03B2, 0xD8FF, 0xDCFF }), 0, 7, new byte[] { 122, 97, 204, 134, 199, 189, 206, 178, 241, 143, 179, 191 } };
            yield return new object[] { "za" + EncodingHelpers.ToString(new int[] { 0x0306, 0x01FD, 0x03B2, 0xD8FF, 0xDCFF }), 4, 3, new byte[] { 206, 178, 241, 143, 179, 191 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0023, 0x0025, 0x03A0, 0x03A3 }), 1, 2, new byte[] { 37, 206, 160 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00C5 }), 0, 1, new byte[] { 0xC3, 0x85 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0065, 0x0065, 0x00E1, 0x0065, 0x0065, 0x8000, 0x00E1, 0x0065, 0xD800, 0xDC00, 0x8000, 0x00E1, 0x0065, 0x0065, 0x0065 }), 0, 15, new byte[] { 0x65, 0x65, 0xC3, 0xA1, 0x65, 0x65, 0xE8, 0x80, 0x80, 0xC3, 0xA1, 0x65, 0xF0, 0x90, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xC3, 0xA1, 0x65, 0x65, 0x65 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00A4, 0x00D0 }) + "aR|{AnGe" + EncodingHelpers.ToString(new int[] { 0x00A3, 0x00A4 }), 0, 12, new byte[] { 0xC2, 0xA4, 0xC3, 0x90, 0x61, 0x52, 0x7C, 0x7B, 0x41, 0x6E, 0x47, 0x65, 0xC2, 0xA3, 0xC2, 0xA4 } };

            // Control codes
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x001F, 0x0010, 0x0000, 0x0009 }), 0, 4, new byte[] { 0x1F, 0x10, 0x00, 0x09 } };

            // Long ASCII strings
            yield return new object[] { "eeeee", 0, 5, new byte[] { 0x65, 0x65, 0x65, 0x65, 0x65 } };
            yield return new object[] { "e" + EncodingHelpers.ToString(new int[] { 0x00E1 }) + "eee", 0, 5, new byte[] { 0x65, 0xC3, 0xA1, 0x65, 0x65, 0x65 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0065, 0x8000, 0x0065, 0x0065, 0x0065 }), 0, 5, new byte[] { 0x65, 0xE8, 0x80, 0x80, 0x65, 0x65, 0x65 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0065, 0xD800, 0xDC00, 0x0065, 0x0065, 0x0065 }), 0, 6, new byte[] { 0x65, 0xF0, 0x90, 0x80, 0x80, 0x65, 0x65, 0x65 } };

            yield return new object[] { "eeeeeeeeeeeeeee", 0, 15, new byte[] { 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65 } };
            yield return new object[] { "eeeeee" + EncodingHelpers.ToString(new int[] { 0x00E1 }) + "eeeeeeee", 0, 15, new byte[] { 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0xC3, 0xA1, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x8000, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065 }), 0, 15, new byte[] { 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0xE8, 0x80, 0x80, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0xD800, 0xDC00, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065, 0x0065 }), 0, 16, new byte[] { 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0xF0, 0x90, 0x80, 0x80, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65 } };

            // 2 bytes
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1 }), 0, 1, new byte[] { 0xC3, 0xA1 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1 }), 0, 5, new byte[] { 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1, 0x0065, 0x00E1, 0x00E1, 0x00E1 }), 0, 5, new byte[] { 0xC3, 0xA1, 0x65, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1, 0x8000, 0x00E1, 0x00E1, 0x00E1 }), 0, 5, new byte[] { 0xC3, 0xA1, 0xE8, 0x80, 0x80, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1, 0xD800, 0xDC00, 0x00E1, 0x00E1, 0x00E1 }), 0, 6, new byte[] { 0xC3, 0xA1, 0xF0, 0x90, 0x80, 0x80, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1 }), 0, 15, new byte[] { 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1, 0x00E1, 0x0065, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1 }), 0, 15, new byte[] { 0xC3, 0xA1, 0xC3, 0xA1, 0x65, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1, 0x00E1, 0x8000, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1 }), 0, 15, new byte[] { 0xC3, 0xA1, 0xC3, 0xA1, 0xE8, 0x80, 0x80, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x00E1, 0x00E1, 0xD800, 0xDC00, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1, 0x00E1 }), 0, 16, new byte[] { 0xC3, 0xA1, 0xC3, 0xA1, 0xF0, 0x90, 0x80, 0x80, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1, 0xC3, 0xA1 } };

            // 3 bytes
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000 }), 0, 1, new byte[] { 0xE8, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000, 0x8000, 0x8000, 0x8000 }), 0, 4, new byte[] { 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000, 0x0065, 0x8000, 0x8000 }), 0, 4, new byte[] { 0xE8, 0x80, 0x80, 0x65, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000, 0x00E1, 0x8000, 0x8000 }), 0, 4, new byte[] { 0xE8, 0x80, 0x80, 0xC3, 0xA1, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000, 0xD800, 0xDC00, 0x8000, 0x8000 }), 0, 5, new byte[] { 0xE8, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000 }), 0, 15, new byte[] { 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000, 0x8000, 0x8000, 0x0065, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000 }), 0, 15, new byte[] { 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0x65, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000, 0x8000, 0x8000, 0x00E1, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000 }), 0, 15, new byte[] { 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xC3, 0xA1, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x8000, 0x8000, 0x8000, 0xD800, 0xDC00, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000 }), 0, 16, new byte[] { 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xE8, 0x80, 0x80 } };

            // Surrogate pairs
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00 }), 0, 2, new byte[] { 240, 144, 128, 128 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0061, 0xD800, 0xDC00, 0x0062 }), 0, 4, new byte[] { 97, 240, 144, 128, 128, 98 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDB80, 0xDC00 }), 0, 2, new byte[] { 0xF3, 0xB0, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDFFF }), 0, 2, new byte[] { 0xF0, 0x90, 0x8F, 0xBF } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDBFF, 0xDC00 }), 0, 2, new byte[] { 0xF4, 0x8F, 0xB0, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDBFF, 0xDFFF }), 0, 2, new byte[] { 0xF4, 0x8F, 0xBF, 0xBF } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00 }), 0, 6, new byte[] { 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00, 0x0065, 0xD800, 0xDC00 }), 0, 5, new byte[] { 0xF0, 0x90, 0x80, 0x80, 0x65, 0xF0, 0x90, 0x80, 0x80 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00, 0x00E1, 0xD800, 0xDC00 }), 0, 5, new byte[] { 0xF0, 0x90, 0x80, 0x80, 0xC3, 0xA1, 0xF0, 0x90, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00, 0x8000, 0xD800, 0xDC00 }), 0, 5, new byte[] { 0xF0, 0x90, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80 } };

            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00 }), 0, 16, new byte[] { 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00, 0x0065, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00 }), 0, 15, new byte[] { 0xF0, 0x90, 0x80, 0x80, 0x65, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00, 0x00E1, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00 }), 0, 15, new byte[] { 0xF0, 0x90, 0x80, 0x80, 0xC3, 0xA1, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00, 0x8000, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00, 0xD800, 0xDC00 }), 0, 15, new byte[] { 0xF0, 0x90, 0x80, 0x80, 0xE8, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80, 0xF0, 0x90, 0x80, 0x80 } };

            // U+FDD0 - U+FDEF
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xFDD0, 0xFDEF }), 0, 2, new byte[] { 0xEF, 0xB7, 0x90, 0xEF, 0xB7, 0xAF } };

            // BOM
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xFEFF, 0x0041 }), 0, 2, new byte[] { 0xEF, 0xBB, 0xBF, 0x41 } };

            // High BMP non-chars
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xFFFD }), 0, 1, new byte[] { 239, 191, 189 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xFFFE }), 0, 1, new byte[] { 239, 191, 190 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xFFFF }), 0, 1, new byte[] { 239, 191, 191 } };


            // Empty strings
            yield return new object[] { string.Empty, 0, 0, new byte[0] };
            yield return new object[] { "abc", 3, 0, new byte[0] };
            yield return new object[] { "abc", 0, 0, new byte[0] };
        }

        [Test(ExpectedCount = 0)]
        public void Encode()
        {
            foreach (var objectse in UTF8EncodingEncodeTests.Encode_TestData())
            {
                string chars = (string)objectse[0];
                int index = (int)objectse[1];
                int count = (int)objectse[2];
                byte[] expected = (byte[])objectse[3];

                EncodingHelpers.Encode(
                new UTF8Encoding(encoderShouldEmitUTF8Identifier: true, throwOnInvalidBytes: false),
                chars, index, count, expected);
                EncodingHelpers.Encode(
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false),
                    chars, index, count, expected);

                EncodingHelpers.Encode(
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true),
                    chars, index, count, expected);
                EncodingHelpers.Encode(
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: true, throwOnInvalidBytes: true),
                    chars, index, count, expected);
            }
        }

        public static IEnumerable<object[]> Encode_InvalidChars_TestData()
        {
            byte[] unicodeReplacementBytes1 = new byte[] { 239, 191, 189 };

            // Lone high surrogate
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800 }), 0, 1, unicodeReplacementBytes1 };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDD75 }), 0, 1, unicodeReplacementBytes1 };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDBFF }), 0, 1, unicodeReplacementBytes1 };

            // Lone low surrogate
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDC00 }), 0, 1, unicodeReplacementBytes1 };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDC00 }), 0, 1, unicodeReplacementBytes1 };

            // Surrogate pair out of range
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00 }), 0, 1, unicodeReplacementBytes1 };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xDC00 }), 1, 1, unicodeReplacementBytes1 };

            // Invalid surrogate pair
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0041, 0xD800, 0xE000 }), 0, 3, new byte[] { 0x41, 0xEF, 0xBF, 0xBD, 0xEE, 0x80, 0x80 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0x0041, 0xDC00 }), 0, 3, new byte[] { 0xEF, 0xBF, 0xBD, 0x41, 0xEF, 0xBF, 0xBD } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0x0041, 0x0042, 0x07FF, 0x0043, 0xDC00 }), 0, 6, new byte[] { 0xEF, 0xBF, 0xBD, 0x41, 0x42, 0xDF, 0xBF, 0x43, 0xEF, 0xBF, 0xBD } };

            // Mixture of ASCII, valid Unicode and invalid unicode
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDD75, 0xDD75, 0xD803, 0xDD75, 0xDD75, 0xDD75, 0xDD75, 0xD803, 0xD803, 0xD803, 0xDD75, 0xDD75, 0xDD75, 0xDD75 }), 0, 14, new byte[] { 239, 191, 189, 239, 191, 189, 240, 144, 181, 181, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 240, 144, 181, 181, 239, 191, 189, 239, 191, 189, 239, 191, 189 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0054, 0x0065, 0x0073, 0x0074, 0xD803, 0x0054, 0x0065, 0x0073, 0x0074 }), 0, 9, new byte[] { 84, 101, 115, 116, 239, 191, 189, 84, 101, 115, 116 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0054, 0x0065, 0x0073, 0x0074, 0xDD75, 0x0054, 0x0065, 0x0073, 0x0074 }), 0, 9, new byte[] { 84, 101, 115, 116, 239, 191, 189, 84, 101, 115, 116 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0054, 0x0065, 0x0073, 0x0074, 0x0054, 0x0065, 0x0073, 0x0074, 0xDD75 }), 0, 9, new byte[] { 84, 101, 115, 116, 84, 101, 115, 116, 239, 191, 189 } };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0x0054, 0x0065, 0x0073, 0x0074, 0x0054, 0x0065, 0x0073, 0x0074, 0xD803 }), 0, 9, new byte[] { 84, 101, 115, 116, 84, 101, 115, 116, 239, 191, 189 } };

            byte[] unicodeReplacementBytes2 = new byte[] { 239, 191, 189, 239, 191, 189 };
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xD800, 0xD800 }), 0, 2, unicodeReplacementBytes2 }; // High, high
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDC00, 0xD800 }), 0, 2, unicodeReplacementBytes2 }; // Low, high
            yield return new object[] { EncodingHelpers.ToString(new int[] { 0xDC00, 0xDC00 }), 0, 2, unicodeReplacementBytes2 }; // Low, low
        }

        [Test]
        public static void GetBytes_ValidASCIIUnicode()
        {
            Encoding encoding = Encoding.UTF8;
            // Bytes has enough capacity to accomodate result
            string s = EncodingHelpers.ToString(new int[] { 0x0054, 0xD83D, 0xDE01, 0x0065, 0x0073, 0x0074 });
            Assert.AreEqual(4, encoding.GetBytes(s, 0, 2, new byte[4], 0));
            Assert.AreEqual(5, encoding.GetBytes(s, 0, 3, new byte[5], 0));
            Assert.AreEqual(6, encoding.GetBytes(s, 0, 4, new byte[6], 0));
            Assert.AreEqual(7, encoding.GetBytes(s, 0, 5, new byte[7], 0));

            char[] c = s.ToCharArray();
            Assert.AreEqual(4, encoding.GetBytes(c, 0, 2, new byte[4], 0));
            Assert.AreEqual(5, encoding.GetBytes(c, 0, 3, new byte[5], 0));
            Assert.AreEqual(6, encoding.GetBytes(c, 0, 4, new byte[6], 0));
            Assert.AreEqual(7, encoding.GetBytes(c, 0, 5, new byte[7], 0));
        }

        [Test]
        public static void GetBytes_InvalidASCIIUnicode()
        {
            Encoding encoding = Encoding.UTF8;
            // Bytes does not have enough capacity to accomodate result
            string s = EncodingHelpers.ToString(new int[] { 0x0054, 0xD83D, 0xDE01, 0x0065, 0x0073, 0x0074 });
            Assert.Throws<ArgumentException>(() => encoding.GetBytes(s, 0, 2, new byte[3], 0));
            Assert.Throws<ArgumentException>(() => encoding.GetBytes(s, 0, 3, new byte[4], 0));
            Assert.Throws<ArgumentException>(() => encoding.GetBytes(s, 0, 4, new byte[5], 0));
            Assert.Throws<ArgumentException>(() => encoding.GetBytes(s, 0, 5, new byte[6], 0));

            char[] c = s.ToCharArray();
            Assert.Throws<ArgumentException>(() => encoding.GetBytes(c, 0, 2, new byte[3], 0));
            Assert.Throws<ArgumentException>(() => encoding.GetBytes(c, 0, 3, new byte[4], 0));
            Assert.Throws<ArgumentException>(() => encoding.GetBytes(c, 0, 4, new byte[5], 0));
            Assert.Throws<ArgumentException>(() => encoding.GetBytes(c, 0, 5, new byte[6], 0));
        }

        [Test]
        public void Encode_InvalidChars()
        {
            foreach (var objectse in UTF8EncodingEncodeTests.Encode_InvalidChars_TestData())
            {
                string chars = (string) objectse[0];
                int index = (int) objectse[1];
                int count = (int) objectse[2];
                byte[] expected = (byte[]) objectse[3];

                EncodingHelpers.Encode(
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: true, throwOnInvalidBytes: false),
                    chars, index, count, expected);
                EncodingHelpers.Encode(
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false),
                    chars, index, count, expected);

                NegativeEncodingTests.Encode_Invalid(
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true),
                    chars, index, count);
                NegativeEncodingTests.Encode_Invalid(
                    new UTF8Encoding(encoderShouldEmitUTF8Identifier: true, throwOnInvalidBytes: true),
                    chars, index, count);
            }
        }
    }
}
#endif
